package com.css.fxfzypg.modules.SettingSeismic.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.common.utils.CheckObjFields;
import com.css.fxfzypg.constants.FxfzConstants;
import com.css.fxfzypg.constants.YNEnum;
import com.css.fxfzypg.modules.SettingSeismic.entity.SettingSeismicDetails;
import com.css.fxfzypg.modules.SettingSeismic.entity.SettingSeismicFault;
import com.css.fxfzypg.modules.SettingSeismic.entity.SettingSeismicPoint;
import com.css.fxfzypg.modules.SettingSeismic.repository.SettingSeismicRepository;
import com.css.fxfzypg.modules.SettingSeismic.service.SettingSeismicService;
import com.css.fxfzypg.modules.SettingSeismic.vo.SettingSeismicDetailsVO;
import com.css.fxfzypg.modules.SettingSeismic.vo.SettingSeismicPointVO;
import com.css.fxfzypg.modules.SettingSeismic.entity.PointLonLatEntity;
import com.css.fxfzypg.modules.baseData.service.FaultageService;
import com.css.fxfzypg.modules.preassesstaskmanage.entity.PreAssessTaskEntity;
import com.css.fxfzypg.modules.preassesstaskmanage.repository.PreAssessTaskRepository;
import com.css.fxfzypg.modules.preassesstaskmanage.service.PreAssessTaskService;
import com.css.fxfzypg.util.*;
import com.css.fxfzypg.web.PlatformSessionContext;
import com.css.fxfzypg.zcpt.sys.entity.SUser;
import com.css.fxfzypg.zcpt.sys.service.SUserService;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: fxfzypg
 * @Author: lhl
 * @CreateDate: 2022/10/13 16:56
 * 设定地震模块
 */
@Service
public class SettingSeismicServiceImpl implements SettingSeismicService {

    @Resource
    SettingSeismicRepository settingSeismicRepository;

    @Resource
    SUserService sUserService;
    @Resource
    PreAssessTaskService preAssessTaskService;
    @Resource
    FaultageService faultageService;
    @Resource
    PreAssessTaskRepository preAssessTaskRepository;

    @Resource
    RedisTemplate<String, String> redisTemplate;

    @Override
    public RestResponse getAll(String taskId) {
        SettingSeismicPointVO vo = new SettingSeismicPointVO();
        vo.setSettingSeismicFault(settingSeismicRepository.getSettingSeismicFaultByTaskId(taskId));
        vo.setDetailsList(settingSeismicRepository.setEarthquakeCensus(taskId, null));
        return RestResponse.succeed(vo);
    }

    @Override
    public RestResponse getSpaceRange(String taskId) {
        return RestResponse.succeed(preAssessTaskService.getById(taskId));
    }

    @Override
    public RestResponse getFault(String taskId) {

        return RestResponse.succeed(faultageService.getFaultByTaskId(taskId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse saveSettingSeismicFault(SettingSeismicFault entity) {
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(entity.getTaskId()))) {
                return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再保存！！！");
            }
            redisTemplate.opsForValue().set(entity.getTaskId(), "21");

            if (PlatformObjectUtils.isNotEmpty(entity.getSfId())) {
                deleteSettingSeismicFault(entity.getSfId(), 1);
            }

            //基准震级与确定震级必须选择一种填写
            if (PlatformObjectUtils.isEmpty(entity.getBenchmarkMagnitude())) {
                if (PlatformObjectUtils.isEmpty(entity.getSettingSeismic())) {
                    return RestResponse.fail("请选择一种震级生成方式！");
                }
            }
            String coordinates1 = entity.getCoordinates();
            String[] coordinates = entity.getCoordinates().split(";");
            if (coordinates.length == 1) {
                entity.setCoordinates(coordinates[0].substring(0, coordinates[0].indexOf(",", coordinates[0].indexOf(",") + 1)));
            } else {
                StringBuilder coordinates2 = new StringBuilder();
                for (String coordinate : coordinates) {
                    coordinates2.append(coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1))).append(";");
                }
                entity.setCoordinates(coordinates2.toString());
            }
            if ("2".equals(entity.getIsAngle())) {
                entity.setAngle(Integer.parseInt(coordinates[0].substring(coordinates[0].lastIndexOf(",") + 1)));
            }
            entity.setSfId(UUIDGenerator.getUUID());
            entity.setSpaceRange(preAssessTaskService.getById(entity.getTaskId()).getTaskRegion());
            String userId = PlatformSessionUtils.getUserId();
            entity.setCreateUserId(userId);
            String user = sUserService.getSUser(userId);
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            entity.setCreateUser(sUser.getUserName());
            entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            entity.setIsDelete(YNEnum.N.toString());
            int i = settingSeismicRepository.saveSettingSeismicFault(entity);
            if (i > 0) {
                entity.setCoordinates(coordinates1);
                saveSettingSeismicPoint1(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            deleteSettingSeismicFault(entity.getSfId(), 1);
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
        return ResponseCreator.createSuccessResponse(null, "保存成功！");
    }

    public RestResponse saveSettingSeismicPoint1(SettingSeismicFault entity) {
        try {
            String[] coordinates = entity.getCoordinates().split(";");
            for (String coordinate : coordinates) {
                SettingSeismicPoint entity1 = new SettingSeismicPoint();
                String substring = coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1));
                entity1.setCoordinates(substring);
                //entity1.setGeom("POINT(" + coordinate.replace(",", " ") + ")");
                String[] split = substring.split(",");
                String geom = "POINT(" + split[0] + " " + split[1] + ")";
                entity1.setGeom(geom);
                entity1.setSsId(UUIDGenerator.getUUID());
                entity1.setBenchmarkMagnitude(entity.getBenchmarkMagnitude());
                entity1.setOperationMagnitude(entity.getOperationMagnitude());
                entity1.setPointSeismicNumber(entity.getSettingSeismicNumber());
                entity1.setDetermineMagnitude(entity.getSettingSeismic());
                entity1.setIsMagnitude(entity.getIsMagnitude());
                entity1.setStepSize(entity.getStepSize());
                entity1.setAngle(Integer.parseInt(coordinate.substring(coordinate.lastIndexOf(",") + 1)));
                entity1.setIsAngle(entity.getIsAngle());
                entity1.setEarthquakeType("2");
                entity1.setSfId(entity.getSfId());
                entity1.setTaskId(entity.getTaskId());
                entity1.setSpaceRange(entity.getSpaceRange());
                entity1.setCreateUserId(entity.getCreateUserId());
                entity1.setCreateUser(entity.getCreateUser());
                entity1.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                entity1.setIsDelete(YNEnum.N.toString());
                int i = settingSeismicRepository.saveSettingSeismicPoint(entity1);
                if (i > 0) {
                    entity1.setCoordinates(coordinate);
                    saveSettingSeismicDetails(entity1);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            deleteSettingSeismicPoint(entity.getSfId(), 1, entity.getTaskId());
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
        return ResponseCreator.createSuccessResponse(null, "保存成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse saveSettingSeismicPoint(SettingSeismicPoint entity) {
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(entity.getTaskId()))) {
                return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再保存！！！");
            }
            redisTemplate.opsForValue().set(entity.getTaskId(), "2");

            //基准震级与确定震级必须选择一种填写
            if (PlatformObjectUtils.isEmpty(entity.getBenchmarkMagnitude())) {
                if (PlatformObjectUtils.isEmpty(entity.getDetermineMagnitude())) {
                    return RestResponse.fail("请选择一种震级生成方式！");
                }
            }
            String coordinates1 = entity.getCoordinates();
            String[] coordinates = entity.getCoordinates().split(";");
            if (coordinates.length == 1) {
                entity.setCoordinates(coordinates[0].substring(0, coordinates[0].indexOf(",", coordinates[0].indexOf(",") + 1)));
            } else {
                StringBuilder coordinates2 = new StringBuilder();
                for (String coordinate : coordinates) {
                    coordinates2.append(coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1))).append(";");
                }
                entity.setCoordinates(coordinates2.toString());
            }
            //entity.setGeom("POINT(" + entity.getCoordinates().replace(",", " ") + ")");
            String[] split = entity.getCoordinates().split(",");
            String geom = "POINT(" + split[0] + " " + split[1] + ")";
            entity.setGeom(geom);
            entity.setSsId(UUIDGenerator.getUUID());
            entity.setEarthquakeType("1");
            String userId = PlatformSessionContext.getUserID();
            entity.setSpaceRange(preAssessTaskService.getById(entity.getTaskId()).getTaskRegion());
            entity.setCreateUserId(userId);
            String user = sUserService.getSUser(userId);
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            entity.setCreateUser(sUser.getUserName());
            entity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            entity.setIsDelete(YNEnum.N.toString());
            int i = settingSeismicRepository.saveSettingSeismicPoint(entity);
            if (i > 0) {
                entity.setCoordinates(coordinates1);
                saveSettingSeismicDetails(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            deleteSettingSeismicPoint(entity.getSsId(), 1, entity.getTaskId());
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
        return ResponseCreator.createSuccessResponse(null, "保存成功！");
    }

    //zyt--批量导入的经纬度保存点状设定地震
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse saveSettingSeismicPoint2(SettingSeismicPoint entity) {
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(entity.getTaskId()))) {
                return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再保存！！！");
            }
            redisTemplate.opsForValue().set(entity.getTaskId(), "2");
            //基准震级与确定震级必须选择一种填写
            if (PlatformObjectUtils.isEmpty(entity.getBenchmarkMagnitude())) {
                if (PlatformObjectUtils.isEmpty(entity.getDetermineMagnitude())) {
                    return RestResponse.fail("请选择一种震级生成方式！");
                }
            }
            String[] coordinates = entity.getCoordinates().split(";");
            if(coordinates!=null && coordinates.length>0){
                for (String coordinate : coordinates) {
                    SettingSeismicPoint entity1 = new SettingSeismicPoint();
                    String substring = coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1));
                    entity1.setCoordinates(substring);//经纬度坐标
                    String[] split = substring.split(",");
                    String geom = "POINT(" + split[0] + " " + split[1] + ")";
                    entity1.setGeom(geom);
                    entity1.setSsId(UUIDGenerator.getUUID());//主键
                    entity1.setBenchmarkMagnitude(entity.getBenchmarkMagnitude());//基准震级-基准震级与确定震级必须选择一种填写
                    entity1.setOperationMagnitude(entity.getOperationMagnitude());//增减震级-区间[0.1,0.5]
                    entity1.setIsMagnitude(entity.getIsMagnitude());//1:基准震级；2:确认震级
                    entity1.setStepSize(entity.getStepSize());//步长-10度/30度/60度
                    entity1.setAngle(Integer.parseInt(coordinate.substring(coordinate.lastIndexOf(",") + 1)));//初始角度
                    entity1.setIsAngle(entity.getIsAngle());//1:最近断层切线角度；2:指定角度
                    entity1.setPointSeismicNumber(entity.getPointSeismicNumber());//点状设定地震个数
                    entity1.setDetermineMagnitude(entity.getDetermineMagnitude());//确认震级
                    entity1.setEarthquakeType("1");//1:点状；2：断层；3：公里格网
                    entity1.setSfId(entity.getSfId());//外键Id
                    entity1.setTaskId(entity.getTaskId());//任务ID
                    entity1.setSpaceRange(entity.getSpaceRange());//空间范围
                    entity1.setCreateUserId(entity.getCreateUserId());//创建人Id
                    entity1.setCreateUser(entity.getCreateUser());//创建人名称
                    entity1.setCreateTime(PlatformDateUtils.getCurrentTimestamp());//创建时间
                    entity1.setIsDelete(YNEnum.N.toString());//删除标识：0未删除，1已删除
                    int i = settingSeismicRepository.saveSettingSeismicPoint(entity1);
                    if (i > 0) {
                        entity1.setCoordinates(coordinate);
                        saveSettingSeismicDetails(entity1);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
        return ResponseCreator.createSuccessResponse(null, "保存成功！");
    }

    /**
     * zyt--导入Excel文件解析批量经纬度
     *
     * @param file 文件
     * @return 导入的信息
     * @throws IOException IO流异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse importExcelPointLonLat(MultipartFile file,String taskId) throws IOException {
        List<PointLonLatEntity> pointLonLatEntities = FileUtil.importExcel(file, 0, 1, PointLonLatEntity.class);
        List<String> coordinatesList = new ArrayList<String>();//已存在的经纬度数组
        List<SettingSeismicPoint> settingSeismicPointList = settingSeismicRepository.getSettingSeismicPointByTaskId(taskId);
        if(settingSeismicPointList!=null && settingSeismicPointList.size()>0){
            for(int i=0;i<settingSeismicPointList.size();i++){
                String coordinates = settingSeismicPointList.get(i).getCoordinates();
                coordinatesList.add(coordinates);
            }
        }
        List<String> lonlatList = new ArrayList<String>();//当前的经纬度数组
        //存储错误的信息
        StringBuilder erorrMesegger = new StringBuilder();
        int count=0;
        for (PointLonLatEntity pointLonLatEntity : pointLonLatEntities) {
            if (CheckObjFields.isAllFieldNull(pointLonLatEntity)){
                count++;
                continue;
            }
            String lonlat = "";
            //判断必填项是否存在空值
            if (PlatformObjectUtils.isEmpty(pointLonLatEntity.getLon()) || PlatformObjectUtils.isEmpty(pointLonLatEntity.getLat())) {
                erorrMesegger.append("第" + (pointLonLatEntities.indexOf(pointLonLatEntity) + 2) + "行数据，必填项存在空值！！<br/>");
                continue;
            }else{
                //校验经纬度是否已存在
                String lon = pointLonLatEntity.getLon();
                String lat = pointLonLatEntity.getLat();
                if (!isNumericFloatLength(lon) || !isNumericFloatLength(lat)) {//判断字符串是否保留2位小数（大于等于0）
                    erorrMesegger.append("第" + (pointLonLatEntities.indexOf(pointLonLatEntity) + 2) + "行数据，经纬度应保留2位小数！<br/>");
                    continue;
                }
                //经纬度保留2位小数
                if(lon.indexOf(".")!=-1){//小数
                    int length = lon.split("\\.")[1].length();
                    if(length==0){
                        lon += "00";
                    }else if(length==1){
                        lon += "0";
                    }
                }else{//整数
                    lon += ".00";
                }
                if(lat.indexOf(".")!=-1){//小数
                    int length = lat.split("\\.")[1].length();
                    if(length==0){
                        lat += "00";
                    }else if(length==1){
                        lat += "0";
                    }
                }else{//整数
                    lat += ".00";
                }
                lonlat = lon + "," + lat;
                if(coordinatesList.contains(lonlat)){
                    erorrMesegger.append("第" + (pointLonLatEntities.indexOf(pointLonLatEntity) + 2) + "行数据，经纬度与已有设定地震点重复！<br/>");
                    continue;
                }
                int index = lonlatList.indexOf(lonlat);
                if(index!=-1){
                    erorrMesegger.append("第" + (pointLonLatEntities.indexOf(pointLonLatEntity) + 2) + "行数据，经纬度与"+(index+1)+"行数据重复！<br/>");
                    continue;
                }
            }
            lonlatList.add(lonlat);
        }
        if (erorrMesegger.length() != 0) {
            return RestResponse.fail("导入失败:".concat(String.valueOf(erorrMesegger)));
        }
        String message = "导入成功" + (pointLonLatEntities.size()-count) + "条!";
        return ResponseCreator.createSuccessResponse(pointLonLatEntities,message);
    }

    //判断字符串是否保留2位小数（大于等于0）
    public static boolean isNumericFloatLength(String str){
        Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        float temp = Float.parseFloat(str);
        if(temp>=0){
            if(str.indexOf(".")!=-1){
                String[] tempStrArr = str.split("\\.");
                if(tempStrArr.length==2){
                    String tempStr = tempStrArr[1];
                    if(tempStr.length()<=2){//保留2位小数
                        return true;
                    }
                }
            }else{//整数
                return true;
            }
        }

        return false;
    }

    public void saveSettingSeismicDetails(SettingSeismicPoint entity) {
        try {
            String[] coordinates = entity.getCoordinates().split(";");
            List<BigDecimal> magnitudes = new ArrayList<>();
            if ("1".equals(entity.getIsMagnitude())) {
                magnitudes = countDetermineMagnitude(entity.getBenchmarkMagnitude(),
                        entity.getOperationMagnitude(), entity.getPointSeismicNumber());
            } else if ("2".equals(entity.getIsMagnitude())) {
                String[] split = entity.getDetermineMagnitude().split(",");
                for (String magnitude : split) {
                    magnitudes.add(new BigDecimal(magnitude));
                }
            }
            List<Integer> angles = null;
            int faultTangentAngle = 0;
            SettingSeismicDetails maxNum = getMaxNum(entity.getTaskId());
            int num = PlatformObjectUtils.isEmpty(maxNum) ? 0 : maxNum.getFaultNum();
            String macroPosition = null;
            for (String coordinate : coordinates) {
                macroPosition = coordinate.substring(coordinate.indexOf(",", coordinate.indexOf(",") + 1) + 1,
                        coordinate.lastIndexOf(","));
                String[] split = coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1)).split(",");
                num++;
                faultTangentAngle = Integer.parseInt(coordinate.substring(coordinate.lastIndexOf(",") + 1));
                if (entity.getStepSize() == 0) {
                    angles = new ArrayList<>();
                    angles.add(faultTangentAngle);
                } else {
                    // if (coordinates.length == 1) {
                    //     faultTangentAngle = entity.getAngle();
                    //     angles = countAngle(entity.getAngle(), entity.getStepSize());
                    // } else {
                    //     faultTangentAngle = Integer.parseInt(coordinate.substring(coordinate.lastIndexOf(",") + 1));
                    angles = countAngle(faultTangentAngle, entity.getStepSize());
                    // }
                }
                for (BigDecimal magnitude : magnitudes) {
                    for (Integer angle : angles) {
                        SettingSeismicDetails settingSeismicDetails = new SettingSeismicDetails();
                        settingSeismicDetails.setId(UUIDGenerator.getUUID());
                        settingSeismicDetails.setLongitude(new BigDecimal(split[0]));
                        settingSeismicDetails.setLatitude(new BigDecimal(split[1]));
                        settingSeismicDetails.setEarthquakeLevel(magnitude);
                        settingSeismicDetails.setAngle(angle);
                        settingSeismicDetails.setFaultNum(num);
                        settingSeismicDetails.setIsDelete(YNEnum.N.toString());
                        settingSeismicDetails.setSsId(entity.getSsId());
                        if ("1".equals(entity.getIsAngle())) {
                            settingSeismicDetails.setFaultTangentAngle(faultTangentAngle);
                        } else {
                            settingSeismicDetails.setFaultTangentAngle(-1);
                        }
                        settingSeismicDetails.setMacroPosition(macroPosition);
                        int i2 = settingSeismicRepository.saveSettingSeismicDetails(settingSeismicDetails);
                    }
                }
                /*if (PlatformObjectUtils.isNotEmpty(entity.getFaultNum())) {
                    settingSeismicRepository.updateFaultNum1(entity.getSsId(), num);
                } else {*/
                    entity.setFaultNum(num);
                    String geom = "POINT(" + split[0] + " " + split[1] + ")";
                    entity.setGeom(geom);
                    entity.setCoordinates(coordinates[0].substring(0, coordinates[0].indexOf(",", coordinates[0].indexOf(",") + 1)));
                    settingSeismicRepository.updateSettingSeismicPoint(entity);
                //}
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
    }

    private SettingSeismicDetails getMaxNum(String taskId) {
        SettingSeismicDetails maxNum = new SettingSeismicDetails();
        PreAssessTaskEntity preAssessTask = preAssessTaskService.getById(taskId);
        PreAssessTaskEntity parTask = new PreAssessTaskEntity();
        if (!"0".equals(preAssessTask.getParentId())) {
            //本身为子任务的  获取父任务
            parTask = preAssessTaskService.getById(preAssessTask.getParentId());
        }else {
            //本身为父任务的
            parTask = preAssessTask;
        }
        //获取父任务下最大的序号
        //获取子任务
        List<PreAssessTaskEntity> subTask = preAssessTaskRepository.getSubTask(parTask.getId());
        if (subTask != null && subTask.size() > 0){
            //含有子任务
            SettingSeismicDetails parMaxNum = settingSeismicRepository.getMaxNum(parTask.getId());
            if (!PlatformObjectUtils.isEmpty(parMaxNum)){
                maxNum = parMaxNum;
            }
            for (PreAssessTaskEntity entity:subTask) {
                SettingSeismicDetails subMaxNum =settingSeismicRepository.getMaxNum(entity.getId());
                if (!PlatformObjectUtils.isEmpty(maxNum) && !PlatformObjectUtils.isEmpty(subMaxNum)){
                    if (subMaxNum.getFaultNum() > maxNum.getFaultNum()){
                        maxNum = subMaxNum;
                    }
                }
            }
        }else {
            //没有子任务
            maxNum = settingSeismicRepository.getMaxNum(taskId);
        }
        return maxNum;
    }

    /**
     * 计算震级
     *
     * @param benchmarkMagnitude 基准震级
     * @param operationMagnitude 增减震级
     * @param pointSeismicNumber 震级个数
     * @return
     */
    private List<BigDecimal> countDetermineMagnitude(BigDecimal benchmarkMagnitude, BigDecimal operationMagnitude,
                                                     int pointSeismicNumber) {
        BigDecimal add = benchmarkMagnitude;//临时存储增震级
        BigDecimal subtract = benchmarkMagnitude;//临时存储减震级
        List<BigDecimal> determineMagnitude = new ArrayList<>();
        determineMagnitude.add(benchmarkMagnitude);
        //点状设定地震个数为1时，不需要增减震级
        if (pointSeismicNumber > 1) {
            for (int i = 1; i < pointSeismicNumber; i++) {
                if (i % 2 == 0) {
                    subtract = subtract.subtract(operationMagnitude);
                    determineMagnitude.add(subtract);
                } else {
                    add = add.add(operationMagnitude);
                    determineMagnitude.add(add);
                }
            }
        }
        return determineMagnitude;
    }

    /**
     * 计算角度
     *
     * @param angle    初始角度
     * @param stepSize 步长
     * @return
     */
    private List<Integer> countAngle(int angle, int stepSize) {
        int add = angle;//临时存储增初始角度
        int subtract = angle;//临时存储减初始角度
        List<Integer> angles = new ArrayList<>();
        while (add <= 180) {
            angles.add(add);
            add = add + stepSize;
        }
        while (subtract > stepSize) {
            subtract = subtract - stepSize;
            angles.add(subtract);
        }
        if (angle == 0) {
            angles.remove(Integer.valueOf(180));
        }
        return angles;
    }


    @Override
    public RestResponse getSettingSeismicPointById(String id) {
        return RestResponse.succeed(settingSeismicRepository.getSettingSeismicPointById(id));
    }

    @Override
    public RestResponse getSettingSeismicDetailsById(String id) {
        return RestResponse.succeed(settingSeismicRepository.getSettingSeismicDetailsById(id));
    }

    @Override
    public List<SettingSeismicDetails> getSettingSeismicDetailsByTaskId(String taskId) {
        return settingSeismicRepository.getSettingSeismicDetailsByTaskId(taskId);
    }

    @Override
    public List<String> getPointDetailByTaskId(String taskId){
        return settingSeismicRepository.getPointDetailByTaskId(taskId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse updateSettingSeismicPoint(SettingSeismicPoint entity) {
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(entity.getTaskId()))) {
                return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再修改！！！");
            }
            redisTemplate.opsForValue().set(entity.getTaskId(), "3");

            deleteSettingSeismicDetails(entity.getSsId(), entity.getTaskId(), 1,false);

            String coordinates1 = entity.getCoordinates();
            String[] coordinates = entity.getCoordinates().split(";");
            if (coordinates.length == 1) {
                entity.setCoordinates(coordinates[0].substring(0, coordinates[0].indexOf(",", coordinates[0].indexOf(",") + 1)));
            } else {
                StringBuilder coordinates2 = new StringBuilder();
                for (String coordinate : coordinates) {
                    coordinates2.append(coordinate.substring(0, coordinate.indexOf(",", coordinate.indexOf(",") + 1))).append(";");
                }
                entity.setCoordinates(coordinates2.toString());
            }
            entity.setUpdateUser(PlatformSessionUtils.getUserId());
            entity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
            //entity.setGeom("POINT(" + entity.getCoordinates().replace(",", " ") + ")");
            String[] split = entity.getCoordinates().split(",");
            String geom = "POINT(" + split[0] + " " + split[1] + ")";
            entity.setGeom(geom);
            settingSeismicRepository.updateSettingSeismicPoint(entity);

            entity.setCoordinates(coordinates1);
            saveSettingSeismicDetails(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(entity.getTaskId());
        }
        return ResponseCreator.createSuccessResponse(null, "修改成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse deleteSettingSeismicFault(String sfId, int isNa) {
        String taskId = settingSeismicRepository.getSettingSeismicFaultById(sfId).getTaskId();
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
                if (isNa == 0) {
                    return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再删除！！！");
                }
            }
            redisTemplate.opsForValue().set(taskId, "41");

            String userId = PlatformSessionUtils.getUserId();
            Timestamp currentTimestamp = PlatformDateUtils.getCurrentTimestamp();
            int i = settingSeismicRepository.deleteSettingSeismicFault(sfId, userId, currentTimestamp);
            if (i > 0) {
                deleteSettingSeismicPoint(sfId, 2, taskId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(taskId);
        }
        return ResponseCreator.createSuccessResponse(null, "删除成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse deleteSettingSeismicPoint(String ssId, int isNa, String taskId) {
        if (isNa == 0) {
            taskId = settingSeismicRepository.getSettingSeismicPointById(ssId).getTaskId();
        }
        try {
            if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
                if (isNa == 0) {
                    return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再删除！！！");
                }
            }
            redisTemplate.opsForValue().set(taskId, "4");

            String userId = PlatformSessionUtils.getUserId();
            Timestamp currentTimestamp = PlatformDateUtils.getCurrentTimestamp();
            List<SettingSeismicPoint> settingSeismicPointBySfId = null;
            int i = 0;
            if (isNa == 2) {
                settingSeismicPointBySfId = settingSeismicRepository.getSettingSeismicPointBySfIdOrderByFaultNum(ssId);
                i = settingSeismicRepository.deleteSettingSeismicPointBySfId(ssId, taskId);
            } else {
                SettingSeismicPoint settingSeismicPointById = settingSeismicRepository.getSettingSeismicPointById(ssId);
                settingSeismicPointBySfId=new ArrayList<>();
                settingSeismicPointBySfId.add(settingSeismicPointById);
                i = settingSeismicRepository.deleteSettingSeismicPoint(ssId, userId, currentTimestamp);
            }
            if (i > 0) {
                for (SettingSeismicPoint seismicPoint : settingSeismicPointBySfId) {
                    i = settingSeismicRepository.updateFaultNum1(ssId, seismicPoint.getFaultNum());
                }

                if (isNa == 2) {
                    for (SettingSeismicPoint seismicPoint : settingSeismicPointBySfId) {
                        deleteSettingSeismicDetails(seismicPoint.getSsId(), taskId, 1,true);
                    }
                } else {
                    deleteSettingSeismicDetails(ssId, taskId, 1,true);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(taskId);
        }
        return ResponseCreator.createSuccessResponse(null, "删除成功！");
    }

    @Transactional(rollbackFor = Exception.class)
    public RestResponse deleteSettingSeismicDetails(String ssId, String taskId, int isNa,boolean bool) {
        if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
            if (isNa == 0) {
                return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再删除！！！");
            }
        }
        redisTemplate.opsForValue().set(taskId, "5");
        try {
            List<SettingSeismicDetails> list = settingSeismicRepository.getSettingSeismicDetailsBySsId(ssId);
            int i = settingSeismicRepository.deleteSettingSeismicDetails(ssId);
            if (i > 0) {
                List<Integer> numList = new ArrayList<>();
                for (SettingSeismicDetails settingSeismicDetails : list) {
                    int faultNum = settingSeismicDetails.getFaultNum();
                    if (!numList.contains(faultNum)) {
                        for (Integer num : numList) {
                            if (num.compareTo(faultNum) < 0) {
                                numList.add(numList.indexOf(num), faultNum);
                                break;
                            }
                        }
                        numList.add(faultNum);
                    }

                }
                for (Integer num : numList) {
                    settingSeismicRepository.updateFaultNum2(taskId, num);
                }

                if(bool){
                    //zyt--删除point
                    /*//逻辑删除point表数据
                    String userId = PlatformSessionUtils.getUserId();
                    Timestamp currentTimestamp = PlatformDateUtils.getCurrentTimestamp();
                    i = settingSeismicRepository.deleteSettingSeismicPoint(ssId, userId, currentTimestamp);*/
                    //zyt--更新point表数据序号
                    i = settingSeismicRepository.updateFaultNum3(taskId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(taskId);
        }
        return ResponseCreator.createSuccessResponse(null, "删除成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse deleteByFaultNum(String faultNum, String taskId) {
        if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(taskId))) {
            return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再删除！！！");
        }
        redisTemplate.opsForValue().set(taskId, "5");
        try {
            int i = settingSeismicRepository.deleteByFaultNum(taskId, Integer.valueOf(faultNum));
            if (i > 0) {
                settingSeismicRepository.updateFaultNum2(taskId, Integer.valueOf(faultNum));

                //zyt--删除point
                //逻辑删除point表数据
                String userId = PlatformSessionUtils.getUserId();
                Timestamp currentTimestamp = PlatformDateUtils.getCurrentTimestamp();
                i = settingSeismicRepository.deleteSettingSeismicPoint2(taskId, userId, currentTimestamp,Integer.valueOf(faultNum));
                //zyt--更新point表数据序号
                i = settingSeismicRepository.updateFaultNum3(taskId);
            }
            return ResponseCreator.createSuccessResponse(i, "删除成功！");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(taskId);
        }
        return RestResponse.fail("删除失败！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse deleteById(String ids) {
        SettingSeismicPoint point = settingSeismicRepository.getSettingSeismicPointBySdId(ids.split(",")[0]);
        if (PlatformObjectUtils.isNotEmpty(redisTemplate.opsForValue().get(point.getTaskId()))) {
            return RestResponse.fail("该任务的设定地震正在被其他人修改，请稍后再删除！！！");
        }
        redisTemplate.opsForValue().set(point.getTaskId(), "5");
        try {
            //int i = settingSeismicRepository.deleteById(id);
            int i = 0;
            String[] split = ids.split(",");
            //查询是否该序号下的detail数据全部删除，则重排序号并删除point
            if(split.length>0) {
                String id0 = split[0];
                //判断details列表
                List<SettingSeismicDetails> list = settingSeismicRepository.getSettingSeismicDetailsBySsId(point.getSsId());
                if (list != null && list.size() > 0 && split.length==list.size()) {//判断是否需要全部删除details列表和point
                    //逻辑删除point表数据
                    deleteSettingSeismicPoint(point.getSsId(),1,point.getTaskId());
                }else{
                    for (String id : split) {
                        i = settingSeismicRepository.deleteById(id);
                    }
                }
            }

            return ResponseCreator.createSuccessResponse(i, "删除成功！");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(point.getTaskId());
        }
        return RestResponse.fail("删除失败！");
    }

    @Override
    public List<SettingSeismicDetailsVO> setEarthquakeCensus(String taskId, String placeProvince) {
        return settingSeismicRepository.setEarthquakeCensus(taskId, placeProvince);
    }

    @Override
    public List<SettingSeismicDetailsVO> setEarthquakeCensus(List<String> taskId, List<String> placeProvince) {
        return settingSeismicRepository.setEarthquakeCensus(taskId, placeProvince);
    }

    @Override
    public Map<String, Object> getDetailPage(SettingSeismicDetailsVO settingSeismicDetailsVO, int curPage, int pageSize) {
        return settingSeismicRepository.getDetailPage(settingSeismicDetailsVO, curPage, pageSize);
    }

    @Override
    public Map<String, Object> getDetailsPage(SettingSeismicDetailsVO settingSeismicDetailsVO, int curPage, int pageSize) {
        return settingSeismicRepository.getDetailsPage(settingSeismicDetailsVO, curPage, pageSize);
    }

    @Override
    public SettingSeismicDetails getSettingSeismicDetailsByInfluenceflieId(String influenceflieId) {
        return settingSeismicRepository.getSettingSeismicDetailsByInfluenceflieId(influenceflieId);
    }

    @Override
    public List<SettingSeismicDetails> getByTaskNumAndLonAndLatAndEqLevel(String taskNum, BigDecimal lon, BigDecimal lat, BigDecimal eqLevel) {
        return settingSeismicRepository.getByTaskNumAndLonAndLatAndEqLevel(taskNum, lon, lat, eqLevel);
    }

    @Override
    public List<SettingSeismicDetailsVO> setEarthquakeCensusNossid(String taskId, String placeProvince) {
        return settingSeismicRepository.setEarthquakeCensusNossid(taskId,placeProvince);
    }

    @Override
    public List<SettingSeismicPoint> getPointsByTaskId(String taskId) {
        return settingSeismicRepository.getPointsByTaskId(taskId);
    }

    @Override
    public List<SettingSeismicDetails> getSettingSeismicDetailsBySsId(String ssId) {
        return settingSeismicRepository.getSettingSeismicDetailsBySsId(ssId);
    }

    @Override
    public int updateFaultNum(SettingSeismicPoint settingSeismicPoint) {
        return settingSeismicRepository.updateFaultNum(settingSeismicPoint);
    }
}
